package com.gupaoedu.rmi;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;

/**
 * 腾讯课堂搜索 咕泡学院
 * 加群获取视频：608583947
 * 风骚的Michael 老师
 */
public class Server {

    public static void main(String[] args) {
        try {
            /**
             *  new的过程中调用父类 UnicastRemoteObject 构造函数
             *  调用Util.createProxy(var4, this.getClientRef(), this.forceStubUse);
             * 生成的是一个动态代理(Remote)Proxy.newProxyInstance(var4, var5, var6);
             * 该动态代理回调函数是 RemoteObjectInvocationHandler
             *
             * Target var6 = new Target(var1, this, var5, this.ref.getObjID(), var3);
             * 其中：var1 = HelloServiceImpl；
             *       var5 = 上文动态代理
             *
             * UnicastRemoteObject的 ref 成员变量
             * transient protected RemoteRef ref;  UnicastServerRef
             *
             * Target 被export 进入 ObjectTable.putTarget(var1);
             */
            IHelloService helloService=new HelloServiceImpl();//已经发布了一个远程对象

            /**
             * 调用Util.createProxy(var4, this.getClientRef(), this.forceStubUse);
             * createStub(var3, var1);
             * 生成的是 RegistryImpl_Stub类
             *
             * Target var6 = new Target(var1, this, var5, this.ref.getObjID(), var3);
             * 其中：var1 = RegistryImpl；
             *       var5 = 上文动态代理
             *
             * UnicastRemoteObject的 ref 成员变量
             * transient protected RemoteRef ref;  UnicastServerRef
             *
             * Target 被export 进入 ObjectTable.putTarget(var1);
             */
            LocateRegistry.createRegistry(1099);

            /**
             *  rebind 方法中调取 Registry registry = getRegistry(parsed);
             *  获取 registry（RegistryImpl_Stub实例）
             * registry.rebind(parsed.name, obj); 执行的同时
             * 二者关联的原因如下：
             *        1、在不断 exportObject 的最后到达 TCPTransport
             *        2、TCPTransport 的 exportObject方法内 listen()启动服务器端监听
             *        3、启动线程 Thread var3 = (Thread)AccessController.doPrivileged(new NewThreadAction(new TCPTransport.AcceptLoop(this.server), "TCP Accept-" + var2, true));
             *                 var3.start();
             *        4、AcceptLoop 的 run 方法内 启动
             *                 TCPTransport.connectionThreadPool.execute(TCPTransport.this.new ConnectionHandler(var1, var3));
             *        5、ConnectionHandler 的 run 方法内
             *              TCPTransport.this.handleMessages(var14, false);
             *        6、handleMessages 方法内  if (!this.serviceCall(var6)) {
             *        7、serviceCall 方法内
             *             Target var5 = ObjectTable.getTarget(new ObjectEndpoint(var39, var40));
             *              ObjectTable.getTarget()做的事情是从socket流中获取ObjId，
             *              并通过ObjId和Transport对象获取Target对象，这里的Target对象已经是服务端的对象。
             *        8、再借由Target的派发器Dispatcher，传入参数服务实现和请求对象RemoteCall，
             *                将请求派发给服务端那个真正提供服务的RegistryImpl的 rebind()方法，
             *                这就是 Skeleton 移交给具体实现的过程了，Skeleton负责底层的操作。
             *   关于  RegistryImpl_Skel 的 dispatch
             *   调用 RegistryImpl 的  rebind lookup  bind  unbind 方法
             *   别的方法 比如 sayHello 会调用
             *          var10 = var42.invoke(var1, var9);
             *
             *
             */
            Naming.rebind("rmi://127.0.0.1/Hello",helloService); //注册中心 key - value
            System.out.println("服务启动成功");
        } catch (RemoteException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }

    }
}
